﻿using System;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Windows.Controls;
using System.Windows.Input;
using TeamLemonApp.Commands;
using TeamLemonApp.DataPersisters;
using TeamLemonApp.Helpers;

namespace TeamLemonApp.ViewModels
{
    public class LoginRegisterFormViewModel : ViewModelBase, IPageViewModel
    {
        private string message;
        private bool isLoggedIn = false;
        private string sessionKey;
        private ICommand loginCommand;
        private ICommand registerCommand;
        private ICommand logoutCommand;

        public LoginRegisterFormViewModel()
        {
        }

        public string Name
        {
            get
            {
                return "Login Form";
            }
        }

        public string Username { get; set; }

        public string Nickname { get; set; }

        public string Message
        {
            get
            {
                return this.message;
            }
            set
            {
                this.message = value;
                this.OnPropertyChanged("Message");
            }
        }

        public string SessionKey
        {
            get
            {
                return this.sessionKey;
            }
            private set
            {
                this.sessionKey = value;
                this.OnPropertyChanged("SessionKey");
            }
        }

        public ICommand Login
        {
            get
            {
                if (this.loginCommand == null)
                {
                    this.loginCommand = new RelayCommand(this.HandleLoginCommand);
                }
                return this.loginCommand;
            }
        }

        public ICommand Register
        {
            get
            {
                if (this.registerCommand == null)
                {
                    this.registerCommand = new RelayCommand(this.HandleRegisterCommand);
                }
                return this.registerCommand;
            }
        }

        public ICommand Logout
        {
            get
            {
                if (this.logoutCommand == null)
                {
                    this.logoutCommand = new RelayCommand(this.HandleLogoutCommand);
                }
                return this.logoutCommand;
            }
        }

        private void HandleLogoutCommand(object parameter)
        {
            DataPersisters.UserDataPersister.LogoutUser(this.sessionKey);
            this.sessionKey = null;
            this.IsLoggedIn = false;
        }

        event EventHandler<LoginSuccessArgs> LoginSuccess;

        public bool IsLoggedIn
        {
            get
            {
                return this.isLoggedIn;
            }
            set 
            { 
                this.isLoggedIn = value;
                this.OnPropertyChanged("IsLoggedIn");
            }
        }

        private void HandleRegisterCommand(object parameter)
        {
            var passwordBox = parameter as PasswordBox;
            var password = passwordBox.Password;

            var authenticationCode = this.GetSHA1HashData(password, Encoding.Default);
            authenticationCode = authenticationCode.ToLowerInvariant();
            UserDataPersister.RegisterUser(this.Username, this.Nickname, authenticationCode);
            this.HandleLoginCommand(parameter);
        }

        private void HandleLoginCommand(object parameter)
        {
            var passwordBox = parameter as PasswordBox;
            var password = passwordBox.Password;
            var authenticationCode = this.GetSHA1HashData(password, Encoding.Default);

            var loggedUser = UserDataPersister.LoginUser(this.Username, authenticationCode);

            if (loggedUser != null)
            {
                this.SessionKey = loggedUser.SessionKey;
                this.IsLoggedIn = true;
            }
        }

        private string GetSHA1HashData(string text, Encoding enc)
        {
            // Convert the input string to a byte array
            byte[] buffer = enc.GetBytes(text);

            // In doing your test, you won't want to re-initialize like this every time you test a
            // string.
            SHA1CryptoServiceProvider cryptoTransformSHA1 =
                new SHA1CryptoServiceProvider();

            // The replace won't be necessary for your tests so long as you are consistent in what
            // you compare.    
            string hash = BitConverter.ToString(
                cryptoTransformSHA1.ComputeHash(buffer)).Replace("-", "");

            return hash;
        }
    }
}